' blitzbasicplugin.bmx

Strict

Import pub.FreeProcess

Import "../maxtk/maxtk.bmx"

'Import axe.MaxEdit

Type TBlitzOptions Extends TOptionsPage

	Field	owner:TBLitzBasicPlugin	
	Field	blitzpluspath:TPathButton
	Field	blitz3dpath:TPathButton
	Field	syntaxhighlight:TButton
	Field	autoindent:TButton
	Field	tabsize:TNumberButton
	Field	editcolor:TColorButton
	Field	editfont:TFontButton
'	Field	editstyle:TTextStyle
	Field	styles:TTextStyle[4]
		
	Method Dirty(cause:TDataNode)
		owner.ResetOptions
		If cause=blitzpluspath And Proceed("Import BlitzPlus Settings?") ImportBBPrefs  blitzpluspath.path
		If cause=blitz3dpath And Proceed("Import Blitz3Ds Settings?") ImportBBPrefs  blitz3dpath.path	
		Super.Dirty cause
	End Method
	
	Function HexToDec( hexcode$ )
		Local l,v,d
		hexcode=hexcode.toupper()
		While hexcode
			d=Asc(hexcode[..1])
			If d<65 d=d-48 Else d=d-55
			v=v*16+d
			hexcode=hexcode[1..]
		Wend
		Return v
	End Function
	
	Method ImportBBPrefs(path$)
		Local stream:TStream
		Local f$,p,a$,b$
		stream=ReadFile(path+"/cfg/blitzide.prefs")
		If Not stream Notify("Could not Import BlitzBasic prefs from~n"+path+"/cfg/blitzide.prefs");Return
		While Not stream.Eof()
			f$=stream.ReadLine()
			f=f.Trim()
			p=f.Find("~t")
			If p>0 a$=f[p+1..];f$=f[..p]
			p=a.find(" ")
			If p>0 b$=a[p+1..];a=a[..p]
			Select f
				Case "font_editor" editfont.set a,Int(b)
				Case "rgb_bkgrnd" editcolor.set HexToDec(a)
'				Case "rgb_default" styles[0].color.set HexToDec(a)
				Case "rgb_ident" styles[0].color.set HexToDec(a)
				Case "rgb_comment" styles[1].color.set HexToDec(a)
				Case "rgb_string" styles[2].color.set HexToDec(a)
				Case "rgb_keyword" styles[3].color.set HexToDec(a)
'				Case "rgb_digit" styles[4].color.set HexToDec(a)
				Case "edit_tabs" tabsize.set Int(a)
			End Select
		Wend
		CloseFile stream
	End Method
	
	Method CreateBBOptions:TBlitzOptions(plugin:TBlitzBasicPlugin)
		SetName "BlitzBasic Options"
		owner=plugin
		plugin.editor.hostoptions.AddPage Self
		blitzpluspath=AddPathButton("BlitzPlus Path","")
		blitz3dpath=AddPathButton("Blitz3D Path","")
		syntaxhighlight=AddButton("Syntax Highlight",2)
		autoindent=AddButton("Automatic Indent",2)
		tabsize=AddNumberButton("Tab Size",4)
		editcolor=AddColorButton("Background",-1)
		editfont=AddFontButton("Font","Courier",12,0)
'		editstyle=AddTextStyle(Self,"Style")'ComboButton("Style",["Normal","Bold","Italic","Bold+Italic"])
		styles=New TTextStyle[4]
		styles[0]=AddTextStyle(Self,"Default")
		styles[1]=AddTextStyle(Self,"Remarks")
		styles[2]=AddTextStyle(Self,"Strings")
		styles[3]=AddTextStyle(Self,"Tokens")
		Layout
		Return Self
	End Method

End Type


Type TBlitzBasicPlugin Extends TPlugin

	Field	editor:TEditor
	Field	options:TBlitzOptions
	Field	tokens:TQuickHelp
	Field	nomods
	Field	editmenu:TGadget
	Field	blitz3dhelp:TDataNode
	
	Field	blitz3dpath$
	Field	blitzpluspath$

	Method Help(cmd$)
		Local l$
		l=cmd.ToLower()	'tokens.link(cmd$)
		If l$ 
			host.Help blitz3dpath+"/help/manual.html#"+l$
		EndIf
	End Method
	
	Method ScanBlitz3DHelp()		
		Local	user:TDataNode
		Local	lang:TDataNode
		Local	cmds:TDataNode	

		Local path$=blitz3dpath+"/help/index.html"
		If FileType(path)=1
			blitz3dhelp=editor.AddLink(host.docroot,"Blitz3D",path)
		EndIf
	
		putenv_ "blitzpath="+blitz3dpath
		Local cmd$=quote(blitz3dpath+"\bin\blitzcc.exe")+" +k"	
				
		Local	process:TProcess
		Local	bytes:Byte[]
		Local	k$

		process=CreateProcess(cmd$,HIDECONSOLE)
		If process
			While True
				bytes=process.pipe.ReadPipe()
				If bytes
					k:+String.FromBytes(bytes,Len bytes)
				Else
					If Not process.status() Exit				
				EndIf
				Delay 10
			Wend
		EndIf
				
		tokens=New TQuickHelp
		While k
			Local n=k.find(Chr(10))
			If n<=0 Exit
			Local t$=k[..n-1]
			Local p=t.find(" ")
			If p=-1 p=t.length
			tokens.AddCommand t[..p],t,""
			k=k[n+1..]
		Wend
	End Method

	Method ScanBlitzPlusHelp()		
		Local	root:TDataNode
'		root=AddLink(helproot,"BlitzPlus",blitzpluspath+"/help/index.html")
'		helproot.refresh
	End Method

	Method ResetOptions()
		Local	path$
		path=RealPath(options.blitz3dpath.path)
		If blitz3dpath<>path
			blitz3dpath=path
			ScanBlitz3DHelp
		EndIf
		path=RealPath(options.blitzpluspath.path)
		If blitzpluspath<>path
			blitzpluspath=path
			ScanBlitzPlusHelp
		EndIf
	End Method

	Method Open:Object(path$)
		Return TBlitzCode.Open(Self,path)
	End Method
	
	Method Initialize(owner:THost)
		host=owner
		SetName("Blitz3D/BlitzPlus Files",["bb"])
		editor=TEditor(host)
		If Not editor RuntimeError "BlitzBasic plugin Required EditorHost"
		options=New TBlitzOptions.CreateBBOptions(Self)
		editmenu=CreateEditMenu()
	End Method

	Function CreateEditMenu:TGadget()
		Local	edit:TGadget
		Const MKEY$=Chr(8)
		edit=CreateMenu("&Edit",0,Null)
		CreateMenu "&Quick Help"+MKEY+"F1",MENUQUICKHELP,edit
		CreateMenu "",0,edit
		CreateMenu "Cu&t"+MKEY+"Ctrl+X",MENUCUT,edit
		CreateMenu "&Copy"+MKEY+"Ctrl+C",MENUCOPY,edit
		CreateMenu "&Paste"+MKEY+"Ctrl+V",MENUPASTE,edit
		CreateMenu "",0,edit
		CreateMenu "Select &All"+MKEY+"Ctrl+A",MENUSELECTALL,edit
		CreateMenu "",0,edit
'		CreateMenu "Block Indent"+MKEY+"Ctrl+TAB",MENUINDENT,edit
'		CreateMenu "Block Outdent"+MKEY+"Shift TAB",MENUOUTDENT,edit
		CreateMenu "Block Indent"+MKEY+"Ctrl+]",MENUINDENT,edit
		CreateMenu "Block Outdent"+MKEY+"Ctrl+[",MENUOUTDENT,edit
		CreateMenu "",0,edit
		CreateMenu "&Find"+MKEY+"Ctrl+F",MENUFIND,edit
		CreateMenu "Find Next"+MKEY+"F3",MENUFINDNEXT,edit
		CreateMenu "&Replace"+MKEY+"Ctrl+H",MENUREPLACE,edit
		CreateMenu "&Goto Line"+MKEY+"Ctrl+G",MENUGOTO,edit
		Return edit
	End Function
End Type


Type TBlitzCode Extends TOpenCode

	Field	blitzplugin:TBlitzBasicPlugin
	Field	options:TBlitzOptions

	Function Open:TBlitzCode(plugin:TBlitzBasicPlugin,path$)
		Local	code:TBlitzCode
		Local	stream:TStream		

		code=New TBlitzCode
		code.blitzplugin=plugin
		code.host=plugin.host		
		code.options=plugin.options
		code.active=True
		code.path=path

		plugin.host.addpanel(code)		
		code.textarea=CreateTextArea(0,0,ClientWidth(code.panel),ClientHeight(code.panel),code.panel,0)
		SetGadgetFilter code.textarea,code.FilterKey,code
		SetTextAreaText code.textarea,"~n"
		SetGadgetLayout code.textarea,1,1,1,1
		code.Refresh
		code.SetDirty False
		plugin.host.UpdateProgress "Reading Stream"
		code.ReadSource(path)
		code.UpdateCode
		code.undolist.clear
' cludge first dirty		
		code.filesrc=TextAreaText(code.textarea)
		code.SetDirty False
		Return code
	End Function

	Method Help()
		Local	p,l$,a$
		If Not blitzplugin.tokens Return
		p=TextAreaCursor(textarea,TEXTAREA_CHARS)
		a$=WordAtPos(cleansrc,p)
		If a$=helpcmd
			blitzplugin.Help a$
		Else
			helpcmd=a$
			helpstring$=blitzplugin.tokens.help(a$)
			UpdateStatus
		EndIf
	End Method

	Method OnEvent()
 		Select EventSource()
			Case textarea 
				Select EventID() 
					Case EVENT_GADGETMENU
						PopupWindowMenu host.window,blitzplugin.editmenu
					Case EVENT_GADGETACTION
						UpdateCode
					Case EVENT_GADGETSELECT
						UpdateCursor
				End Select
		End Select
	End Method

	Method Refresh()
		Local	rgb:TColorButton
		Local	src$
		SetTextAreaTabs textarea,options.tabsize.value
		SetTextAreaFont textarea,options.editfont.font
		rgb=options.editcolor
		SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,True
		rgb=options.styles[0].color
		SetTextAreaColor textarea,rgb.red,rgb.green,rgb.blue,False
		src=cleansrc
		cleansrc=""
		cleansrcl=""
		cursorpos=0
		SetCode(src)
	End Method

	Method BuildSource(quick,debug,gui,run)		
		Local cmd$,out$,arg$
		
		Local bbpath$=blitzplugin.blitz3dpath

		putenv_ "blitzpath="+bbpath
		
		cmd$=quote(bbpath+"\bin\blitzcc.exe")
		If debug cmd=cmd+" -d"
		
'		putenv_ "blitzpath="+bbpath
'		cmd$=quote(bbpath+"bin/blitzcc.exe")	
'		If run cmd$:+" -x"
'		If debug cmd$:+" -d" Else cmd$:+" -r"	'-v
		cmd$:+" "+quote(host.FullPath(path))
		If run
			arg$=host.GetCommandLine()
			If arg cmd$:+" "+arg
		EndIf
		host.execute Self,cmd,"Building "+StripExt(StripDir(path)),"",True	',exe$		

	End Method

'"D:/blitz3d/testkey.bb":2:2:2:2:Function 'hjk' not found

	Method Process$(command$)
		Local file$,line,col,msg$
		Local p,q
		
		p=command.Find("~n~q")
		If p>-1
			p=p+2
			q=command.Find("~q",p)
			file=command[p..q]
			p=command.Find(":",q)
			q=command.Find(":",p+1)
			line=Int(command[p+1..q])
			p=command.Find(":",q+1)
			col=Int(command[q+1..p])
			p=command.FindLast(":")
			msg$=command[p+1..]			
			Notify msg$
			host.SetStatus msg
			host.DebugSource file,line,col
		EndIf
	End Method


	Method GetNode:TDataNode()
		Local	root:TCodeNode,n:TCodeNode
		Local	src$,line,col
		Local	p,p1,r,t,m,f,l,e

'		if codenode return codenode		
		n=New TCodeNode
		n.name=StripDir(path)
		n.owner=Self
		n.count=src.length
		root=n
'update rem,type,method,function,label pointers
		src=cleansrcl
		p1=src.length
		p=-1;r=-1;t=-1;m=-1;f=-1;l=-1
		While p<p1			'src.length
			While r<=p
				r=FindToken("rem",src,r+1)
			Wend
			While t<=p
				t=FindToken("type",src,t+1)
			Wend
			While m<=p
				m=FindToken("method",src,m+1)
			Wend
			While f<=p
				f=FindToken("function",src,f+1)
			Wend
			While l<=p
				l=FindLabel(src,l+1)
			Wend
			If r<t And r<m And r<f And r<l
				p=FindEndToken("rem",src,r+1,True)
				Continue
			EndIf
			p=Min(t,Min(m,Min(f,l)))
			If p=src.length Exit		
			While (n And n.parent And p>n.pos+n.count) 
				n=TCodeNode(n.parent)
			Wend
			If t<m And t<f And t<l
				e=src.find(EOL,t)
				n=n.AddCodeNode(cleansrc[t..e],t,FindEndToken("type",src,t,True))
				p=t+1
				Continue
			EndIf
			If m<f And m<l
				e=src.find(EOL,m)
				n.AddCodeNode(cleansrc[m..e],m,e)
				p=m+1
				Continue
			EndIf
			If f<l
				e=src.find(EOL,f)
				n.AddCodeNode(cleansrc[f..e],f,e)
				p=f+1
				Continue		
			Else
				e=src.find(EOL,l)
				n.AddCodeNode(cleansrc[l..e],l,e)
				p=l+1
				Continue				
			EndIf
		Wend
		If codenode
			codenode.Sync(root)	
			root.Free
		Else
			codenode=root
		EndIf
		Return codenode
	End Method

	Function IsCode(src$,p)
		Local	l,q,n
		l=src.FindLast(EOL$,src.length-p)
		If l=-1 l=0
		q=src.Find(";",l)
		If q<>-1 And q<p Return
		q=l
		While q<p
			q=src.Find(Chr(34),q)+1
			If q=0 Exit
			If q<=p n:+1
		Wend
		If n&1 Return
		Return True		
	End Function

	Function FindLabel(src$,pos)
		Local	p,q,c
		While pos>=0
			p=src.Find("#",pos)
			If p=-1 Exit
			q=p
			While q>0
				q:-1
				c=src[q]
				If c=13 Return p
				If c=10 Return p
				If c=32 Or c=9 Continue
				Exit
			Wend
			If q=0 Return p
			pos=p+1
		Wend
		Return src.length	
	End Function
	
	Function FindToken(token$,src$,pos)	'lowercase src only!
		Local	p,c,n
		n=token.length
		While pos>=0
			p=src.Find(token,pos)
			If p=-1 Exit
			c=10 If p>0 c=src[p-1]
			If isntalphanumeric(c) 
				If p+n<src.length c=src[p+n]
				If isntalphanumeric(c) 
					If iscode(src,p)
						If p<4 Or src[p-4..p]<>"end " Return p
					EndIf
				EndIf
			EndIf
			pos=p+1
		Wend
		Return src.length
	End Function

	Function FindEndToken(token$,src$,pos,returnlast=False)	'if true returns first character after endtoken
		Local	p,q,e$,n
		
		p=pos
		e$="end"+token
		n=e.length
		While p<src.length
			p=src.Find(e$,p)
			If p=-1 Exit
			If p+n=src.length Or isntalphanumeric(src[p+n])
				If iscode(src,p)
					If p=0 Or isntalphanumeric(src[p-1]) Exit
				EndIf
			EndIf
			p=p+n
		Wend
		If p=-1 p=src.length Else If returnlast p:+n
		q=pos
		e$="end "+token
		n=e.length
		While q<src.length
			q=src.Find(e$,q)
			If q=-1 Exit
			If q+n=src.length Or isntalphanumeric(src[q+n])
				If iscode(src,q)
					If q=0 Or isntalphanumeric(src[q-1]) Exit
				EndIf
			EndIf
			q=q+n
		Wend
		If q=-1 q=src.length Else If returnlast q:+n
		Return Min(p,q)
	End Function

	Function IsFirstCharOnLine(src$,pos)
		Local	i,c
		For i=1 To pos
			c=src[pos-i]
			If c=10 Or c=13 Return True
			If c>32 Return False
		Next
		Return True
	End Function

' rem and endrem must be first nonwhitespace on line - following funcs are for lowercase src only

	Function FindRem(src$,pos)
		While pos<src.length
			pos=FindToken("rem",src,pos)
			If pos=src.length Exit
			If IsFirstCharOnLine(src,pos) Return pos
			pos:+1
		Wend
		Return pos
	End Function

	Function FindEndRem(src$,pos,returnlast=False)
		Local	i,c		
		While pos<src.length
			pos=FindEndToken("rem",src,pos)
			If pos=src.length Exit
			If IsFirstCharOnLine(src,pos)
				If returnlast 
					If src[pos+5]=Asc("e") Or src[pos+5]=Asc("E") pos:+1
					pos:+6
				EndIf
				Return pos
			EndIf
			pos:+1
		Wend
		Return src.length
	End Function

	Function FindPrevRem(src$,pos)	'lowercase src only!
		Local	p,c
		While pos>0
			If pos>src.length Exit
			p=src.FindLast("rem",src.length-pos)
			If p=-1 Exit						
			If isntalphanumeric(src[p+3]) And IsFirstCharOnLine(src,p) Return p			
			pos=p-1
		Wend
		Return -1
	End Function

	Method WasRemmed(pos,src$)
		Local	s$,p
		s$=cleansrcl
		p=src.length-s.length
		If p<0 pos:-p		
		p=FindPrevRem(s$,pos+3)
		If p=-1 Return
		p=FindEndRem(s$,p)
		If pos<p Return True
	End Method

	Method SetCode(src$,diff:TDiff=Null)
		Local	i,p,p1,q,r,a,t$,h$,lsrc$,r0,r1,cpos,autocap
		Local	s:TTextStyle

' update dirty flag	
		CheckDirty src
		If src=cleansrc And Not deferpos And Not diff Return	
		
		Local bbtokens:TQuickHelp=blitzplugin.tokens

		If Not bbtokens Or Not options.syntaxhighlight	'Not isbmx Or 
			cleansrc=src
			cleansrcl=src.ToLower()
			Return
		EndIf	
' doit
		autocap=True		'autocapitalize
		lsrc=src.ToLower()
		cpos=TextAreaCursor(textarea,TEXTAREA_CHARS)
		LockTextArea textarea
' calculate highlight region
		If deferpos
			p=deferpos
			p1=p
			deferpos=0
		Else
			If diff
				p=diff.pos
				p1=p+diff.add.length
			Else
				p=firstdiff(src,cleansrc)
				p1=lastdiff(src,cleansrc)
			EndIf
			q=src.length-cleansrc.length
			If p1-p<q p1=p+q
			If p1<p p1=p
		EndIf
' round region to line breaks
		If p>0 p:-1
		If p>src.length p=src.length
		p=src.findlast(EOL,src.length-p)+1
		p1=src.find(EOL,p1)+1
		If p1=0 p1=Len src
' if endrem between p0,p1 and next rem after p1 move p1 forwards
		r1=FindEndRem(lsrc,p)
		If r1<p1 And wasremmed(r1+6,lsrc)
			r0=FindRem(lsrc,r1+6)
			If r0>p1 p1=r0
		EndIf
' if rem between p0,p1 and matching endrem after p1 move p1 forewards 
		r0=FindPrevRem(lsrc,p1)
		If r0>=p And r0+3<>cpos	'defer fix
			r1=FindEndRem(lsrc,r0,True)
			If r1>p1 p1=r1
		EndIf
' if rem before p0 and matching endrem after p0 highlight to endrem and move p0 forwards
		r0=FindPrevRem(lsrc,p)
		If r0<>-1 And r0<p
			r1=FindEndRem(lsrc,r0,True)
			If r1>p
				s=options.styles[COMMENT]
				If r1>p s.Format(textarea,p,r1-p)
				If autocap And r1<src.length
					If lsrc[r1-6..r1]="endrem" And src[r1-6..r1]<>"EndRem" SetTextAreaText textarea,"EndRem",r1-6,6
					If lsrc[r1-7..r1]="end rem" And src[r1-7..r1]<>"End Rem" SetTextAreaText textarea,"End Rem",r1-7,7
				EndIf
				p=r1
			EndIf
		EndIf	
' if was remmed and now isn't move p1 down to nearest rem or endrem
		If WasRemmed(p,lsrc)
			r0=FindRem(lsrc,p)
			r1=FindEndRem(lsrc,r0,True)
			p1=Max(p1,Min(r0,r1))	
		EndIf
' highlight code
		s=options.styles[NORMAL]
		If p1>p s.format(textarea,p,p1-p)
		While p<p1
			host.UpdateProgress("Highlighting Code",(p*100)/p1)
			a=src[p]
' quoted strings
			If a=34
				q=p1
				r=src.find(Chr(34),p+1)
				If r>-1 And r<q q=r+1
				r=src.find(EOL,p+1)
				If r>-1 And r<q q=r
				s=options.styles[QUOTED]
				s.format(textarea,p,q-p)
				p=q
				Continue
			EndIf
' single line comments
			If a=59
				q=p1
				r=src.find(EOL,p+1)
				If r>-1 And r<q q=r
				s=options.styles[COMMENT]
				s.format(textarea,p,q-p)
				p=q
				Continue				
			EndIf
' tokens
			If (a>=65 And a<91) Or (a>=97 And a<123) Or (a=95)
				q=p+1
				While q<p1
					a=src[q]
					If a<46 Exit
					If a=47 Exit
					If a>=58 And a<65 Exit
					If a>=91 And a<95 Exit
					If a=96 Exit
					If a>122 Exit
					q:+1
				Wend
				t$=src[p..q]
				h$=bbtokens.token(t$)
				If h$
					If h$<>t$ And autocap
						If q<>cpos
							SetTextAreaText textarea,h$,p,Len h
						Else
							deferpos=q
						EndIf
					EndIf
					s=options.styles[KEYWORD]
					s.format(textarea,p,q-p)
				EndIf
				p=q
				Continue
			EndIf
			p:+1
		Wend
		UnlockTextArea textarea
		cleansrc=src
		cleansrcl=lsrc
		CheckDirty src
	End Method
	
End Type



'	Method DocMods()
'		quickhelp=TQuickHelp.Create(bmxpath)
'		RefreshAll
'	End Method

Rem
	Global tempcount


	Method BuildSource(quick,debug,gui,run)		
		Local cmd$,out$,arg$
		cmd$=quote(bmkpath)
		cmd$:+" makeapp"
		If run cmd$:+" -x"
		If debug cmd$:+" -d" Else cmd$:+" -r"	'-v
		If gui cmd$:+" -t gui"
		If Not quick cmd$:+" -a"
		If debug 
			out$=StripExt(host.FullPath(path))+".debug"
			cmd$:+" -o "+quote(out$)+" "			'QUOTES+out$+QUOTES+" "
		EndIf		
		cmd$:+" "+quote(host.FullPath(path))
		If run
			arg$=host.GetCommandLine()
			If arg cmd$:+" "+arg
		EndIf
		host.execute cmd,"Building "+StripExt(StripDir(path)),"",True	',exe$		
	End Method

EndRem
	



Rem
' codeplay.bbcode

Strict

Import "host.bmx"
Import "opencode.bmx"
Import "quickhelp.bmx"

'Const QUOTES$=Chr(34)


	Method ScanBlitz3DHelp()		
		Local	root:TDataNode
		Local	user:TDataNode
		Local	lang:TDataNode
		Local	cmds:TDataNode	

'		root=helproot.AddNode("Blitz3D")
'		root=AddLink(helproot,"Blitz3D",blitz3dpath+"/help/index.html")
		user=root.AddNode("UserGuide")
		lang=root.AddNode("Language")
		cmds=root.AddNode("Commands")
'		helppanel.AddLink root,"Samples",b3dpath+"/samples/index.html"
		helproot.refresh
	End Method

	Method ScanBlitzPlusHelp()		
		Local	root:TDataNode
'		root=AddLink(helproot,"BlitzPlus",blitzpluspath+"/help/index.html")
		helproot.refresh
	End Method

EndRem

Rem
	Global tempcount

	Function Create:TBBCode(path$,owner:THost)
		Local	code:TBBCode
		Local	stream:TStream		

		If Not blitz3dpath blitz3dpath=GetBlitz3DPath()		
		If Not blitzpluspath blitzpluspath=GetBlitzPlusPath()		

		If Not bbtokens
			bbtokens=TQuickHelp.Create(blitz3dpath)
		EndIf

'		If Not bmxpath Notify "BlitzMax Not Found";Return

		If path
			stream=ReadFile(path)
			If Not stream 
				Notify "Open could not read from "+path
				Return Null
			EndIf
			CloseStream stream
		Else
			path=owner.temppath+"/tmp/untitled"+tempcount+".bb"
			If Not CreateFile(path)
				CreateDir owner.temppath+"/tmp"
				path=owner.temppath+"/tmp/untitled"+tempcount+".bb"
				If Not CreateFile(path)
					Notify "Could not create temp file at "+path
					Return
				EndIf
			EndIf
			tempcount:+1
		EndIf
		
		code=New TBBCode
'		code.isbmx=True
		code.host=owner		
		code.options=TEditorOptions(owner.editoroptions)'OptionsRequester(owner.options)
		code.active=True
		code.path=path
		code.editmenu=CreateEditMenu()
		owner.addpanel(code)		
		code.textarea=CreateTextArea(0,0,ClientWidth(code.panel),ClientHeight(code.panel),code.panel,0)
		SetTextAreaText code.textarea,"~n"
		SetGadgetLayout code.textarea,1,1,1,1
		code.Refresh
		code.SetDirty False
		stream=ReadFile(path)
		If stream
			owner.UpdateProgress "Reading Stream",0
			code.ReadSource(stream)
			CloseFile stream
		Else
'			code.SetDirty False
			ActivateGadget code.textarea
		EndIf		
		code.UpdateCode
		code.undolist.clear
' cludge first dirty		
		code.filesrc=TextAreaText(code.textarea)
		code.SetDirty False
		Return code
	End Function
EndRem

